from urllib.parse import unquote

from channels.db import database_sync_to_async
from rest_framework_simplejwt.tokens import AccessToken

from user.models import ClientUser


class WsTokenVerify:
    """
    websocket 认证类
    """

    def __init__(self, inner):
        self.inner = inner

    async def __call__(self, scope, receive, send):
        query_string = scope["query_string"].decode()
        if not query_string:
            raise ValueError("请求未认证")

        # 解析 token
        qus = query_string.split("=")
        if len(qus) != 2:
            raise ValueError("错误的请求头")
        token_value = unquote(qus[1])
        parts = token_value.split(" ")
        if len(parts) != 2:
            raise ValueError("错误的请求头")
        validated_token = AccessToken(parts[1])

        # 获取当前请求用户信息
        user_id = validated_token['user_id']
        user = await self.get_user(user_id)

        # 将当前请求用户加入scope
        scope['user'] = user
        return await self.inner(scope, receive, send)

    @database_sync_to_async
    def get_user(self, user_id):
        try:
            user = ClientUser.objects.get(id=user_id, del_flag=False)
        except ClientUser.DoesNotExist:
            raise ValueError("用户不存在")
        return user
